home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OCFSRC.PAK / AUTOCLI.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  7KB  |  292 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.7  $
  6. //
  7. // OLE Automation Client Implementation
  8. //----------------------------------------------------------------------------
  9. #include <ocf/pch.h>
  10. #if !defined(OCF_AUTODEFS_H)
  11. # include <ocf/autodefs.h>
  12. #endif
  13. #if !defined(SERVICES_MEMORY_H)
  14. # include <services/memory.h>
  15. #endif
  16. #if !defined(CLASSLIB_POINTER_H)
  17. # include <classlib/pointer.h>
  18. #endif
  19.  
  20. TAutoProxyArgs::~TAutoProxyArgs()
  21. {
  22. }
  23.  
  24. //
  25. //
  26. void TAutoProxy::Bind(const char* progid)
  27. {
  28.   PRECONDITION(progid);
  29.  
  30.   GUID guid;
  31.   TXOle::Check(CLSIDFromProgID(OleStr(progid), &guid), progid);
  32.   Bind(guid);
  33. }
  34.  
  35. //
  36. //
  37. void TAutoProxy::Bind(const GUID& guid)
  38. {
  39.   IUnknown* unk;
  40.   HRESULT stat = ::CoCreateInstance(guid,0,CLSCTX_SERVER,IID_IUnknown,(void FAR*FAR*)&unk);
  41.   if (stat != HR_NOERROR) {
  42.     char guidBuf[60];
  43.     TClassId copy(guid);
  44.     lstrcpy (guidBuf, copy);
  45.     TXOle::Check(stat, guidBuf);
  46.   }
  47.   Bind(unk);
  48. }
  49.  
  50. //
  51. //
  52. void TAutoProxy::Bind(IUnknown* unk)
  53. {
  54.   if (!unk)
  55.     return;
  56.   IDispatch* dsp;
  57.   HRESULT stat = unk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&dsp);
  58.   unk->Release();
  59.   TXOle::Check(stat, "IUnknown");
  60.   Bind(dsp);
  61. }
  62.  
  63. //
  64. //
  65. void TAutoProxy::Bind(IDispatch* dsp)
  66. {
  67.   Unbind();
  68.   That = dsp;
  69. }
  70.  
  71. //
  72. //
  73. void TAutoProxy::Bind(IUnknown& unk)
  74. {
  75.   IDispatch* dsp;
  76.   TXOle::Check(unk.QueryInterface(IID_IDispatch, (void FAR* FAR*)&dsp), "IUnknown");
  77.   Bind(dsp);
  78. }
  79.  
  80. //
  81. //
  82. void TAutoProxy::Bind(IDispatch& obj)
  83. {
  84.   Unbind();
  85.   obj.AddRef();
  86.   That = &obj;
  87. }
  88.  
  89. //
  90. //
  91. void TAutoProxy::Bind(TAutoVal& val)
  92. {
  93.   if (val.GetDataType() == atVoid)
  94.     That = 0;
  95.   else
  96.     // NOTE: The following call throws exception in case of failure
  97.     //
  98.     Bind((IDispatch&)val);
  99. }
  100.  
  101. //
  102. //
  103. void TAutoProxy::MustBeBound()
  104. {
  105.   if (!That)
  106.     TXAuto::Raise(TXAuto::xNotIDispatch);
  107. }
  108.  
  109. //
  110. //
  111. IDispatch* TAutoProxy::GetObject(const char* progid)
  112. {
  113.   CLSID clsid;
  114.   TXOle::Check(CLSIDFromProgID(OleStr(progid), &clsid));
  115.  
  116.   LPUNKNOWN  punk  = 0;
  117.   LPDISPATCH pdisp = 0;
  118.   HRESULT hr = GetActiveObject(clsid, 0, &punk);
  119.   if (SUCCEEDED(hr)) {
  120.     punk->QueryInterface(IID_IDispatch,
  121.                          (void**)&pdisp);
  122.     punk->Release();
  123.   }
  124.   return pdisp;
  125. }
  126.  
  127. //
  128. //
  129. long TAutoProxy::Lookup(const char far* name)
  130. {
  131.   if (!name)
  132.     name = "(null)";  // force controlled failure
  133.   long id;
  134.  
  135.   MustBeBound();
  136. #if defined(BI_OLECHAR_WIDE)
  137.   TString tsname(name);
  138.   wchar_t* wname = tsname;
  139.   TXOle::Check(That->GetIDsOfNames(IID_NULL, &wname, 1, Lang, &id), name);
  140. #else
  141.   TXOle::Check(That->GetIDsOfNames(IID_NULL, &const_cast<char far*>(name), 1, Lang, &id), name);
  142. #endif
  143.   return id;
  144. }
  145.  
  146. void TAutoProxy::Lookup(const char far* names, long* ids, unsigned count)
  147. {
  148.   MustBeBound();
  149.  
  150. #if defined(BI_OLECHAR_WIDE)
  151.   const char far* pc = names;
  152.   int i;
  153.   for (i = 0; i < count; i++) {
  154.     pc += strlen(pc) + 1;
  155.   }
  156.   wchar_t* wnames = TUString::ConvertAtoW(names, pc-names-1);
  157.   wchar_t** args = new wchar_t far*[count];
  158.   wchar_t* pw = wnames;
  159.   for (i = 0; i < count; i++) {
  160.     args[i] = pw;
  161.     pw += lstrlenW(pw) + 1;
  162.   }
  163.   HRESULT stat = That->GetIDsOfNames(IID_NULL, args, count, Lang, ids);
  164.   delete wnames;
  165. #else
  166.   char far** args = new char far*[count];
  167.   const char far* pc = names;
  168.   for (int i = 0; i < count; i++) {
  169.     args[i] = (char far*)pc; // for non-unicode, names separated by null bytes
  170.     pc += strlen(pc) + 1;
  171.   }
  172.   HRESULT stat = That->GetIDsOfNames(IID_NULL, args, count, Lang, ids);
  173. #endif
  174.  
  175.   delete[] args;
  176.   if (stat) {
  177.     int bad = 0;
  178.     if ((stat = HR_DISP_UNKNOWNNAME) != HR_NOERROR)
  179.       while (bad < count && ids[bad] != DISPID_UNKNOWN) {
  180.         bad++;
  181.         names += (strlen(names) + 1);
  182.       }
  183.     TXOle::Check(stat, names);
  184.   }
  185. }
  186.  
  187. TAutoVal&
  188. TAutoProxy::Invoke(uint16 attr, TAutoProxyArgs& args,
  189.                    long* ids, unsigned named)
  190. {
  191.   // Check that we're bound
  192.   //
  193.   MustBeBound();
  194.  
  195.   VARIANT* retval = 0;
  196.   if (!(attr & (acPropSet | acVoidRet))) {
  197.  
  198.     // NOTE: The first TAutoVal/VARIANT of TAutoProxyArgs (really TAutoArgs)
  199.     //       is for the return value...
  200.     retval = args;
  201.  
  202.   }
  203.  
  204.   DISPID funcId = ids[0];
  205.   DISPPARAMS params;
  206.   params.cArgs = args;
  207.   params.cNamedArgs = named;
  208.   params.rgvarg = args;
  209.   params.rgdispidNamedArgs = ids;
  210.   if (attr & acPropSet) {
  211.     ids[0] = DISPID_PROPERTYPUT;
  212.     params.cNamedArgs++;
  213.     params.cArgs++;
  214.   } else {
  215.     params.rgdispidNamedArgs++;
  216.     params.rgvarg++;
  217.   }
  218.  
  219.   unsigned int errarg = 0;
  220.   EXCEPINFO errinfo = {0};
  221.   HRESULT stat = That->Invoke(funcId, IID_NULL, Lang,
  222.                               uint16(attr & (acMethod | acPropSet | acPropGet)),
  223.                               ¶ms, retval, &errinfo, &errarg);
  224.  
  225.   // Restore function id incase PropSet
  226.   //
  227.   ids[0] = funcId;
  228.  
  229.   // Check for failure
  230.   //
  231.   if (stat != HR_NOERROR) {
  232.     TAPointer<char> errMsg = new char[100];
  233.  
  234.     // Is there additional informatiol in the EXCEPINFO structure
  235.     //
  236.     if (stat == ResultFromScode(DISP_E_EXCEPTION)) {
  237.       TString str(errinfo.bstrDescription);
  238.       char *errDesc = errinfo.bstrDescription ? (char*)str : "";
  239.       wsprintf(errMsg, "Invoke ID= %ld/%lX (%s) %s=%X", funcId, funcId,
  240.                        errDesc,
  241.                        errinfo.wCode ? "wCode" : "scode",
  242.                        errinfo.wCode ? errinfo.wCode : errinfo.scode);
  243.     }
  244.     else if (stat == ResultFromScode(DISP_E_TYPEMISMATCH) ||
  245.              stat == ResultFromScode(DISP_E_PARAMNOTFOUND)) {
  246.       wsprintf(errMsg, "Invoke ID= %ld/%lX, arg Index:%d", funcId, funcId,
  247.                         errarg);
  248.     }
  249.     else {
  250.       wsprintf(errMsg, "Invoke Id= %ld/%lX", funcId, funcId);
  251.     }
  252.     TXOle::Check(stat, errMsg);
  253.   }
  254.   return args;
  255. }
  256.  
  257. TAutoEnumeratorBase::TAutoEnumeratorBase(const TAutoEnumeratorBase& copy)
  258. {
  259.   Current.Copy(copy.Current);
  260.   Iterator = copy.Iterator;
  261.   if (Iterator)
  262.     TXOle::Check(Iterator->Clone(&Iterator));
  263. }
  264.  
  265. void TAutoEnumeratorBase::operator =(const TAutoEnumeratorBase& copy)
  266. {
  267.   Current.Copy(copy.Current);
  268.   Unbind();
  269.   Iterator = copy.Iterator;
  270.   if (Iterator)
  271.     TXOle::Check(Iterator->Clone(&Iterator));
  272. }
  273.  
  274. void TAutoEnumeratorBase::Bind(TAutoVal& val)
  275. {
  276.   Unbind();
  277.   IUnknown& unk = val;
  278.   TXOle::Check(unk.QueryInterface(IID_IEnumVARIANT, (void far* far*) &Iterator),
  279.                "_NewEnum");
  280. }
  281.  
  282. bool TAutoEnumeratorBase::Step()
  283. {
  284.   Clear();
  285.   if (!Iterator)
  286.     TXOle::Check(HR_NOINTERFACE, "_NewEnum");
  287.   else if (HRIsOK(Iterator->Next(1,(VARIANT far*)&Current,0)))
  288.     return true;
  289.   return false;
  290. }
  291.  
  292.